import arrayMethods from "./array.js";

export function observe(data) {
  if (typeof data !== "object" || data === null) {
    return;
  }
  // 如果这个对象被劫持过了 就不需要再劫持了
  if (data.__ob__) {
    return data.__ob__;
  }

  //对这个对象进行响应式处理 如果一个对象被劫持过了 就不需要再劫持了
  return new Observer(data);
}
class Observer {
  constructor(data) {
    Object.defineProperty(data, "__ob__", {
      value: this,
      enumerable: false,
      writable: true,
      configurable: true,
    });
    // data.__ob__ = this;
    //object.defineProperty 只能劫持已经存在的属性
    // 新增 和 删除属性 不能被检测到
    if (Array.isArray(data)) {
      //  重写数组方法 7个可以改变数组本身的方法
      data.__proto__ = arrayMethods;
      this.observeArray(data);
    } else {
      // 对象的响应式处理
      this.walk(data);
    }
  }
  // 遍历数组的所有元素 处理数组中的对象
  observeArray(data) {
    data.forEach((item) => {
      observe(item);
    });
  }
  // 遍历对象的所有属性 并对每个属性进行响应式处理
  walk(data) {
    Object.keys(data).forEach((key) => {
      defineReactive(data, key, data[key]);
    });
  }
}
export function defineReactive(obj, key, val) {
  // 递归处理  深度响应式
  observe(val);
  //闭包
  Object.defineProperty(obj, key, {
    // 取属性值时调用
    get() {
      return val;
    },
    // 设置属性值时调用
    set(newVal) {
      if (newVal === val) {
        return;
      }
      // 对新值进行响应式处理
      observe(newVal);
      val = newVal;
    },
  });
}
